package filesync;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopy {
    /*static public void visitDirExample(File source, File target, String[] patterns) {
        new FileSystemVisitor(new FileSystemVisitorListener() {
            @Override
            public void onFile(File f) {
                System.out.println("onFile " + f.getAbsolutePath());
            }

            @Override
            public void onDirectory(File f) {
                System.out.println("onDirectory " + f.getAbsolutePath());
            }            
        }).visitAllDirsAndFiles(source);
    }*/
    
    static public void createDir(File dir) {
        dir.mkdir();
    }

    // Modified http://www.exampledepot.com/egs/java.io/CopyFile.html
    // Copies src file to dst file. If the dst file does not exist, it is created
    static public void copyFile(File src, File dst) throws IOException {
        if (src.exists() && dst.exists() && FileUtil.same(src, dst))
            return;

        File path = dst.getParentFile();
        if (!path.exists()) //does the destination already exist?
            //if not we need to make it exist if possible (note this is mkdirs not mkdir)
            if (!path.mkdirs())
                throw new IOException("copyFiles: Could not create direcotry: " + path.getAbsolutePath() + ".");
        
        FileInputStream fin = null;
        FileOutputStream fout = null;
        byte[] buffer = new byte[4096]; //Buffer 4K at a time (you can change this).
        int bytesRead;
        try {
            fin =  new FileInputStream(src);
            fout = new FileOutputStream (dst);
            //while bytesRead indicates a successful read, lets write...
            while ((bytesRead = fin.read(buffer)) >= 0)
                fout.write(buffer,0,bytesRead);
        } catch (IOException e) { //Error copying file... 
            IOException wrapper = new IOException("copyFiles: Unable to copy file: " + 
                src.getAbsolutePath() + "to" + dst.getAbsolutePath()+".");
            wrapper.initCause(e);
            wrapper.setStackTrace(e.getStackTrace());
            throw wrapper;
        } finally { //Ensure that the files are closed (if they were open).
            if (fin != null)
                fin.close();
            if (fout != null)
                fout.close();
        }
    }

    static public void copyFile(File src, File dst, String[] patterns) throws IOException {
        if (FileUtil.matches(src.getAbsolutePath(), patterns))
            copyFile(src, dst);
    }

    public static void copyFiles(File src, File dest) throws IOException {
        copyFiles(src, dest, null);
    }
    
    // Modified from http://www.dreamincode.net/code/snippet1443.htm
    /**
     * This function will copy files or directories from one location to another.
     * note that the source and the destination must be mutually exclusive. This 
     * function can not be used to copy a directory to a sub directory of itself.
     * The function will also have problems if the destination files already exist.
     * @param src -- A File object that represents the source for the copy
     * @param dest -- A File object that represnts the destination for the copy.
     * @throws IOException if unable to copy.
     */
    public static void copyFiles(File src, File dest, String[] patterns) throws IOException {
        //Check to ensure that the source is valid...
        if (!src.exists())
            throw new IOException("copyFiles: Can not find source: " + src.getAbsolutePath()+".");
        else if (!src.canRead()) //check to ensure we have rights to the source...
            throw new IOException("copyFiles: No right to source: " + src.getAbsolutePath()+".");

        //is this a directory copy?
        if (src.isDirectory())  {
            if (!dest.exists()) //does the destination already exist?
                //if not we need to make it exist if possible (note this is mkdirs not mkdir)
                if (!dest.mkdirs())
                    throw new IOException("copyFiles: Could not create direcotry: " + dest.getAbsolutePath() + ".");

            String list[] = src.list(); //get a listing of files...
            for (int i = 0; i < list.length; i++) { //copy all the files in the list.
                File dest1 = new File(dest, list[i]);
                File src1 = new File(src, list[i]);
                copyFiles(src1 , dest1, patterns);
            }
        } else
            copyFile(src, dest, patterns); //This was not a directory, so lets just copy the file
    }
}
